package com.gestocasa.model;

import java.util.Vector;

import com.gestocasa.dao.BaseDAO;
import com.gestocasa.dao.DAOException;

public class SchemeManager {

	private BaseDAO dao; 
	private Scheme scheme;
	private Vector<LoggerRegisters> loggerRegisters;
	private boolean schemeDirty;
	private boolean dataDirty;
	
	public SchemeManager(BaseDAO dao) {
		this.dao = dao;
		this.scheme = new Scheme();
		this.loggerRegisters = new Vector<LoggerRegisters>();
		
		schemeDirty = false;
		dataDirty = false;
	}
	
	private void initializeLoggerRegisters() {
		if(scheme != null) {
			loggerRegisters = new Vector<LoggerRegisters>();
			for(Area a : scheme.getAreas()) {
				for(Configuration c : a.getConfigurations()) {
					loggerRegisters.add(new LoggerRegisters(a, c));
				}
			}
		}
	}
	
	private LoggerRegisters searchLogger(LoggerRegisters logger) {
		LoggerRegisters source = null;
		for(LoggerRegisters lr : loggerRegisters) {
			if(lr.getArea().equals(logger.getArea()) == true) {
				if(lr.getConfiguration().equals(logger.getConfiguration()) == true) {
					source = lr;
				}
			}
		}
		return source;
	}
	
	public Scheme getScheme() {
		return scheme;
	}
	
	public Vector<LoggerRegisters> getLoggerRegisters() {
		return loggerRegisters;
	}
	
	public BaseDAO getDAO () {
		return dao;
	}

	public boolean isNeedSaveScheme() {
		return schemeDirty;
	}
	
	public boolean isNeedSaveData() {
		return dataDirty;
	}
	
	public boolean setSchemeAttributes(Scheme scheme, Vector<Attribute> attributes) {
		if(scheme == null || attributes == null) {
			return true;
		}
		
		scheme.getAttributes().clear();
		for(Attribute a : attributes) {
			scheme.getAttributes().add(new Attribute(a));
		}
		return true;
	}
	
	public LoggerRegisters getLoggerRegister(Configuration c) {
		for(LoggerRegisters lr : loggerRegisters) {
			if(lr.getConfiguration() == c) {
				return lr;
			}
		}
		return null;
	}
	
	private boolean searchAndUpdateLoggerRegister(LoggerRegisters logger) {
		LoggerRegisters source = searchLogger(logger);
		if(source != null) {
			source.getRegisters().clear();
			for(Register r : logger.getRegisters()) {
				source.getRegisters().add(new Register(r));
			}
			return true;
		}
		return false;
	}
	
	public boolean updateSchemeAreas(Scheme scheme, Vector<Area> areas) {
		if(scheme == null || areas == null) {
			return true;
		}
		
		scheme.getAreas().clear();
		for(Area a : areas) {
			scheme.getAreas().add(new Area(a));
		}
				
		schemeDirty = true;
		return true;
	}
	
	public boolean updateLoggerRegister(LoggerRegisters logger) {
		if(logger == null) {
			return true;
		}
		
		if(searchAndUpdateLoggerRegister(logger) == true) {
			dataDirty = true;
		}
		return true;
	}
	
	public boolean loadScheme() {
		boolean result = true;
		
		if(dao.isOpened() == false) { 
			dao.open();
		}
		
		try {
			Scheme schemeLoaded = dao.loadSchemeData();
			if(schemeLoaded == null) {
				result = false;
			}
			else {
				scheme = schemeLoaded;
				initializeLoggerRegisters();
				schemeDirty = false;
			}
		}
		catch(DAOException e) {
			result = false;
		}

		return result;
	}
	
	public boolean saveScheme() {
		boolean result = true;
		
		if(schemeDirty == true) {
			if(dao.isOpened() == false) { 
				dao.open();
			}
			
			try {
				result = dao.saveSchemeData(scheme);
				if(result == true) {
					schemeDirty = false;
				}
			}
			catch(DAOException e) {
				System.out.println(getClass().getName() + " : " + e.getMessage());
				result = false;
			}
		}
		
		return result;
	}
	
	public boolean loadRegisters() {
		boolean result = true;
		
		if(scheme == null) {
			result = false;
		}
		else {
			if(dao.isOpened() == false) { 
				dao.open();
			}
			
			try {
				Vector<LoggerRegisters> loggerList = dao.loadRegistersData(scheme);
				if(loggerList == null) {
					result = false;
				}
				else {
					for(LoggerRegisters logger : loggerList) {
						searchAndUpdateLoggerRegister(logger);
					}
					dataDirty = false;
				}
			} catch (DAOException e) {
				result = false;
			}
		}

		return result;
	}
	
	public boolean saveRegisters() {
		boolean result = true;
		
		if(dataDirty == true) {
			if(dao.isOpened() == false) { 
				dao.open();
			}
			
			try {
				result = dao.saveRegistersData(scheme, loggerRegisters);
				if(result == true) {
					dataDirty = false;
				}
			} catch (DAOException e) {
				System.out.println(getClass().getName() + " : " + e.getMessage());
				result = false;
			}
		}
		
		return result;
	}
}
